import cn.hutool.core.io.FileUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.sl.core.engine.utils.BeanUtil;
import com.sl.core.utils.JsonUtil;
import io.github.bonigarcia.wdm.WebDriverManager;
import lombok.SneakyThrows;
import org.apache.commons.compress.utils.Lists;
import org.mozilla.universalchardet.UniversalDetector;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.devtools.Command;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v136.network.Network;
import org.openqa.selenium.devtools.v136.network.model.Request;
import org.openqa.selenium.devtools.v136.network.model.RequestId;
import org.openqa.selenium.devtools.v136.network.model.Response;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class OpenNavigate {
    private static final Logger LOGGER = Logger.getLogger(OpenNavigate.class.getName());
    private static final String OUTPUT_FILE = "m3u8_links.txt";

    public static void main(String[] args) throws UnsupportedEncodingException {

        // 配置日志
        configureLogging();

        // 设置URL
        String url = "https://www.doubao.com/chat/5200784360820738";

        // 配置Chrome选项
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--remote-allow-origins=*");
        options.addArguments("--disable-blink-features=AutomationControlled");
        options.addArguments("--no-sandbox");
        // 设置浏览器的默认编码为UTF-8
        options.addArguments("--lang=zh-CN");
        options.addArguments("--encoding=UTF-8");

        options.addArguments("--disable-dev-shm-usage");
        options.addArguments("--window-size=1920,1080");
        options.setCapability("goog:loggingPrefs", Map.of("browser", "ALL"));

        // 使用WebDriverManager自动管理驱动
        WebDriverManager.chromedriver().setup();

        // 创建WebDriver实例
        WebDriver driver = new ChromeDriver(options);
        DevTools devTools = ((ChromeDriver) driver).getDevTools();

        try {
            // 建立DevTools会话
            devTools.createSession();
            LOGGER.info("DevTools会话已创建");

            // 启用Network域监听
            devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
            LOGGER.info("网络请求监听已启用");

            // 创建文件用于保存m3u8链接
            Path outputPath = Paths.get(OUTPUT_FILE);
            Files.deleteIfExists(outputPath);
            Files.createFile(outputPath);
            LOGGER.info("输出文件已创建: " + OUTPUT_FILE);

            // 监听请求事件
            devTools.addListener(Network.requestWillBeSent(), request -> {
                Request req = request.getRequest();
                String requestUrl = req.getUrl();
                if (requestUrl.contains("playlist.m3u8")) {
//                    LOGGER.info("===== 拦截到m3u8请求 =====");
//                    LOGGER.info("URL: " + requestUrl);
//                    LOGGER.info("Method: " + method);

                    // 保存链接到文件
                    try {
                        Files.writeString(outputPath, requestUrl + "\n", java.nio.file.StandardOpenOption.APPEND);
                        LOGGER.info("链接已保存到文件");
                    } catch (IOException e) {
                        LOGGER.log(Level.SEVERE, "保存链接到文件失败", e);
                    }

                    // 这里不再立即退出，而是标记发现了m3u8链接
                    // driver.quit(); // 注释掉立即退出，改为继续监控
                }
            });
//            // 监听响应事件（可选）
            devTools.addListener(Network.responseReceived(), response -> {


                Response res = response.getResponse();
                //
                String url1 = res.getUrl();
                if (url1.contains("samantha/chat/completion")) {
                    // 异步获取响应内容
                    CompletableFuture<Void> contentFuture = getResponseContent(devTools,res,response.getRequestId());
                    contentFuture.thenRun(() -> System.out.println("响应内容处理完成"));


                    // 这里不再立即退出，而是标记发现了m3u8链接
                    // driver.quit(); // 注释掉立即退出，改为继续监控
                }
//                LOGGER.finer("响应状态: " + res.getStatus() + " URL: " + res.getUrl());
            });

            // 导航到目标URL
            LOGGER.info("导航到URL: " + url);
            driver.get(url);

            // 使用显式等待代替固定休眠
            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));

            try {
                // 等待页面上某个元素加载完成（根据实际情况修改）
                wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".semi-input-textarea")));
                LOGGER.info("页面主体元素已加载");
                Thread.sleep(1000);
// 方式1：使用ID定位元素并输入字符
                try {

                    WebElement webElement = driver.findElement(By.cssSelector(".semi-modal-confirm-content"));
                    if (ObjectUtil.isNotNull(webElement)) {
                        webElement.sendKeys(Keys.ESCAPE);
                    }
                } catch (Exception e) {

                }
                WebElement elementById = driver.findElement(By.cssSelector(".semi-input-textarea"));

                //
                elementById.sendKeys("请问你在干什么");
                elementById.sendKeys(Keys.ENTER);


                // 滚动页面触发更多加载（可选）
                scrollPage(driver);


                // 等待一段时间继续监控网络请求
                Thread.sleep(11115000);

            } catch (TimeoutException e) {
                LOGGER.warning("页面加载超时: " + e.getMessage());
            }

        } catch (Exception e) {
            LOGGER.log(Level.SEVERE, "发生异常: ", e);
        } finally {
            // 关闭资源
            if (devTools != null) {
                devTools.close();
                LOGGER.info("DevTools会话已关闭");
            }
            if (driver != null) {
                driver.quit();
                LOGGER.info("WebDriver已退出");
            }
        }
    }

    // 异步获取响应内容的方法
    @SneakyThrows
    private static CompletableFuture<Void> getResponseContent(DevTools devTools,Response res , RequestId requestId) {
        Thread.sleep(8000);
        LOGGER.info("===== 等待成功 =====");
        return CompletableFuture.runAsync(() -> {
            try {
                Command<Network.GetResponseBodyResponse> responseBody1 = Network.getResponseBody(requestId);
                // 获取响应内容
                Network.GetResponseBodyResponse responseBody = devTools.send(
                        responseBody1
                );
                LOGGER.info("===== 获取响应成功 =====");

                // 处理响应内容（可能是JSON、HTML等）

                String rawContent = responseBody.getBody();
                byte[] rawBytes = rawContent.getBytes();
                UniversalDetector detector = new UniversalDetector(null);
                detector.handleData(rawBytes, 0, rawBytes.length);
                detector.dataEnd();
                String encoding = detector.getDetectedCharset();

                if (encoding == null) {
                    encoding = "UTF-8";
                }

                String mimeType = res.getMimeType();
                // 关键：修复编码
//                byte[] rawBytes = rawContent.getBytes(StandardCharsets.ISO_8859_1);
                String content = rawContent;//new String(rawBytes, StandardCharsets.UTF_8);

                List<String> result = Lists.newArrayList();
                List<String> split = StrUtil.split(content, "\n");

                for (String s : split) {
                    if (StrUtil.contains(s, "data:")) {
                        Map<String, Object> map = JsonUtil.toMap(StrUtil.replace(s, "data:", ""));
                        if (MapUtil.isEmpty(map)) {
                            continue;
                        }
                        Map<String, Object> map1 = JsonUtil.toMap(BeanUtil.getProperty(map, "$.event_data"));

                        Object property = BeanUtil.getProperty(map1, "$.message.content");
                        if (ObjectUtil.isNotNull(property)) {

                            byte[] bytes = property.toString().getBytes(StandardCharsets.ISO_8859_1);
                            String fixed = new String(bytes, encoding);
                            System.out.println(fixed);
                            result.add(fixed);
                        }
                    }
                }

                System.out.println("响应内容: " + content);
                File file = FileUtil.file("/Users/weixin/work/project/self/square-lake/square-lake-app/src/test/java/1.txt");
                if (!file.exists()) {
                    file.createNewFile();
                }
                // 保存链接到文件
                FileUtil.writeString(JsonUtil.toStr(result), file, StandardCharsets.UTF_8);
                LOGGER.info("链接已保存到文件");

                // 可以在这里添加JSON解析逻辑
                // if (isJsonResponse(responseBody.getMimeType())) {
                //     parseJsonContent(content);
                // }

            } catch (Exception e) {
                System.err.println("获取响应内容失败: " + e.getMessage());
            }
        });
    }

    // 配置日志记录
    private static void configureLogging() {
        try {
            // 创建文件处理器
            FileHandler fileHandler = new FileHandler("webscraper.log", true);
            fileHandler.setFormatter(new SimpleFormatter());

            // 获取根日志器并添加处理器
            Logger rootLogger = Logger.getLogger("");
            rootLogger.addHandler(fileHandler);

            // 设置日志级别
            rootLogger.setLevel(Level.INFO);

            LOGGER.info("日志配置完成");
        } catch (IOException e) {
            System.err.println("配置日志失败: " + e.getMessage());
        }
    }

    // 滚动页面方法
    private static void scrollPage(WebDriver driver) {
        try {
            LOGGER.info("开始滚动页面以触发更多加载");
            // 使用JavaScript执行滚动操作
            for (int i = 0; i < 3; i++) {
                ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight);");
                Thread.sleep(2000);
            }
            LOGGER.info("页面滚动完成");
        } catch (Exception e) {
            LOGGER.warning("滚动页面时发生异常: " + e.getMessage());
        }
    }

}